
<template>
  <div>
    <!-- 横向 -->
    <view class='wrapper horizontal-box' id='scale-wrapper' :style="{background: stylesObj.bgoutside}" v-if="direction=== 'horizontal'">
      <view class='scale-mask' v-if="!scroll"/>
      <!-- 选中的横条  -->
      <view class='zz' :style="{backgroundColor: stylesObj.lineSelect}"/>
      <scroll-view
        class='scroll-view'
        :scroll-x="true"
        :scroll-left="centerNum"
        :scroll-with-animation="true"
        @scroll="bindscroll"
        :show-scrollbar="false"
        :enhanced="true"
      >

        <view class='scroll-wrapper'>
          <!-- 左补白 -->
          <view class='seat' :style="{width: windowWidth/2 + 'px'}"/>

          <!-- 标尺容器 -->
          <view  class='scale-container'>
            <view class='scale-wrapper'>
              <view class='scale-grip'
                    v-for="(item, index) in grid"
                    :key="index"
                    :style="{height:h + 'px', borderColor: stylesObj.line }">
                <view class='scale-grip-item'
                      v-for="(it, idx) in 10"
                      :key="idx"
                      :style="{width: single + 'px', height: idx===4?'80':'60' + '%', borderColor: stylesObj.line}"
                />
              </view>
            </view>
            <!-- 标尺数显示，长度：每格长度*个数 -->
            <view class='scale-vaule-wrapper' :style="{width: single*10*grid + 'px', color: stylesObj.fontColor, fontSize: stylesObj.fontSize + 'px'}">
              <view class='scale-value first-scale-value' :style="{width: single*10 + 'px'}">{{min}}</view>
              <view v-if="int" style="display: flex;">
                <view
                  class='scale-vaule'
                  v-for="(item, index) in grid"
                  :key="index"
                  :style="{width:single*10 + 'px'}">{{min+10*(index+1)}}
                </view>
              </view>
              <view v-else style="display: flex;">
                <view
                  class='scale-vaule'
                  v-for="(it, index) in grid"
                  :key="index"
                  :style="{width: single*10 + 'px'}">{{min+(index+1)}}
                </view>
              </view>
            </view>
          </view>

          <!-- 右补白 -->
          <view class='seat' :style="{width: windowWidth/2 + 'px'}"/>
        </view>
      </scroll-view>
    </view>

    <!-- 竖向 -->
    <view class='wrapper vertical-box' id='scale-wrapper' :style="{background: stylesObj.bgoutside}" v-else-if="direction === 'vertical'">
      <view class='scale-mask' v-if="!scroll"/>
      <view class='zz' :style="{backgroundColor: stylesObj.lineSelect}"/>
      <scroll-view
        class='scroll-view'
        style="height: 600rpx;"
        :scroll-y="true"
        :scroll-top="centerNum"
        :scroll-with-animation='true'
        @scroll="bindscroll"
        :show-scrollbar="false"
        :enhanced="true">

        <view class='scroll-wrapper'>
          <!-- 左补白 -->
          <view class='seat' :style="{height: windowHeight/2 - single*10/2 + 'px'}"/>

          <!-- 标尺容器 -->
          <view  class='scale-container'>
            <view class='scale-wrapper' :style="{height: single*10*grid + 'px', paddingTop: single*10/2 + 'px'}">
              <view class='scale-grip'
                    v-for="(item, index) in grid"
                    :key="index"
                    :style="{borderColor: stylesObj.line}">
                <view class='scale-grip-item'
                      v-for="(it, idx) in 10"
                      :key="idx"
                      :style="{height: single + 'px', width: (idx==4||idx==9) ? '80':'60' + '%', borderColor: stylesObj.line}"
                />
              </view>
            </view>
            <!-- 标尺数显示，长度：每格长度*个数 -->
            <view class='scale-vaule-wrapper'
                  :style="{height: single*10*(grid+1) + 'px', color: stylesObj.fontColor, fontSize: stylesObj.fontSize + 'px'}">
              <view class='scale-value' :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min}}</view>
              <view v-if="int">
                <view class='scale-vaule'
                      v-for="(item, index) in grid"
                      :key="index"
                      :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min+10*(index+1)}}
                </view>
              </view>
              <view v-else>
                <view class='scale-vaule'
                      v-for="(it, index) in grid"
                      :key="index"
                      :style="{height: single*10 + 'px', lineHeight: single*10 + 'px'}">{{min+(index+1)}}
                </view>
              </view>
            </view>
          </view>

          <!-- 右补白 -->
          <view class='seat' :style="{height: windowHeight/2 - single*10/2 + 'px'}"/>
        </view>
      </scroll-view>
    </view>
  </div>
</template>

<script>
/**
 min[number] 默认值 0, // 最小值
 max[number] 默认值 100, // 最大值
 int[boolean] 默认值 true, // 是否开启整数模式 ，false为小数模式  true 整数模式
 single[number] 默认值 10, // 单个格子的实际长度（单位rpx）
 h[number] 默认值 0,// 自定义高度 初始值为80
 active[null] 默认值 center ，// 自定义选中位置  （三个值 min, max ,center , 范围内合法数值）
 styles[object]  // 自定义卡尺样式
 */

export default {
  name: '',
  components: {},
  props: {
    // 最小值
    min: {
      type: Number,
      default: 0,
    },
    // 最大值
    max: {
      type: Number,
      default: 100,
    },
    // 是否开启整数模式
    int: {
      type: Boolean,
      default: false,
    },
    // 每个格子的实际行度 （单位px ，相对默认值）
    single: {
      type: Number,
      default: 10,
    },
    // 高度
    h: {
      type: Number,
      default: 80,
    },
    // 是否禁止滚动
    scroll: {
      type: Boolean,
      default: true,
    },
    // 方向
    direction: {
      type: String,
      default: 'horizontal',
    },
    // 当前选中
    active: {
      type: null,
      default: '0',
    },
    styles: {
      type: Object,
      default: () => {},
    },

  },
  data() {
    return {
      defaultStyles: {
        line: '#dbdbdb', // 刻度颜色
        bginner: '#fbfbfb', // 前景色颜色
        bgoutside: '#dbdbdb', // 背景色颜色
        lineSelect: '#6643e7', // 选中线颜色
        fontColor: '#404040', // 刻度数字颜色
        fontSize: 16, // 字体大小
      },
      rul: {},
      windowHeight: 0,
      windowWidth: '',
      horizontalTime: null,
      verticalTime: null,
      grid: '',
      centerNum: '',
      stylesObj: {},
    };
  },
  computed: {},
  watch: {},
  onReady() {
    const min = parseInt(this.min, 10) || 0;
    const max = parseInt(this.max, 10) || 100;
    this.min = min;
    this.max = max;
    this.init();
  },
  created() {
  },
  mounted() {
  },
  methods: {
    // 初始化
    init() {
      // 设置默认值
      const min = this.min || 0;
      const max = this.max || 0;
      /**
       * grid 外层的刻度尺，里面有10个小刻度尺(10个小刻度尺直接拿10遍历出来)
       * 整数：
       *  需要除以10，此时里面的一个小刻度尺代表1
       *  例如：30-80 此时需要5个外层刻度尺。
       * 小数：
       *  不需要除以10，此时里面的一个小刻度尺代表0.1
       *  例如：30-80 此时需要50个外层刻度尺。
       *
       */
      let grid;
      if (this.int) {
        grid = (max - min) / 10;
      } else {
        grid = (max - min);
      }
      this.stylesObj = Object.assign(this.defaultStyles, this.styles);
      this.grid = grid;

      // 当前选中的 active
      let activeVal = this.selectActiveVal();
      if (activeVal < min || activeVal > max) { // 默认数字不合理
        activeVal = (min + max) / 2;
      }
      if (this.int) {
        let diff = (activeVal - min) / 10; // 移动diff格
        /* eslint-disable-next-line */
        if (diff < 0 || isNaN(diff) || !diff) diff = 0;
        // this.single 每个小格子长度
        const centerNum = diff * this.single * 10;
        setTimeout(() => { this.centerNum = centerNum; }, 200);
      } else {
        const diff1 = (activeVal - min) * 10; // 移动diff格
        const centerNum = diff1 * this.single;
        setTimeout(() => { this.centerNum = centerNum; }, 200);
      }
      //  获取节点信息，获取节点宽度
      const query = this.createSelectorQuery().in(this);
      query.select('#scale-wrapper').boundingClientRect(() => {
        // res.top; // 这个组件内 #the-id 节点的上边界坐标
      }).exec((e) => {
        this.windowWidth = e[0].width;
        this.windowHeight = e[0].height;
      });
    },
    // 给定的选中默认值
    selectActiveVal() {
      // 当前选中位置设置
      let activeVal;
      if (this.active === 'min') {
        activeVal = this.min;
      } else if (this.active === 'max') {
        activeVal = this.max;
      } else if (this.active === 'center') {
        activeVal = (this.min + this.max) / 2;
      } else {
        activeVal = this.active ? this.active : this.min;
      }
      return activeVal;
    },
    // 滚动
    bindscroll(e) {
      // 移动的距离
      let offset = 0;
      if (this.direction === 'vertical') {
        offset = e.detail.scrollTop;
      } else {
        offset = e.detail.scrollLeft;
      }
      // 选中的值
      let value;
      if (this.int) {
        value = this.min + (offset / this.single);
        value = Math.round(value);
        if (value > this.max) value = this.max;
        this.$emit('value', value);
        const centerNum = (value - this.min) * this.single + Math.random() ** 10;
        clearTimeout(this.horizontalTime);
        this.horizontalTime = setTimeout(() => {
          this.centerNum = centerNum;
          this.$emit('value', value);
        }, 100);
      } else {
        value = this.min + ((offset / this.single) / 10);
        value = value.toFixed(1);
        if (value > this.max) value = this.max;
        this.$emit('value', value);
        const centerNum = (value - this.min) * this.single * 10 + Math.random() ** 10;
        clearTimeout(this.verticalTime);
        this.verticalTime = setTimeout(() => {
          this.centerNum = centerNum;
          this.$emit('value', value);
        }, 100);
      }
    },
  },
};
</script>

<style lang="less" scoped>
  view,text {
    box-sizing: border-box;
  }
  .wrapper {
    position: relative;
  }
  .scale-mask {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 100;
  }
  .horizontal-box {
    padding-top: 7%;
    .scroll-wrapper {
      position: relative;
      display: flex;
    }
    .zz {
      position: absolute;
      left: 50%;
      top: 0;
      transform: translate(-50%);
      height: 40%;
      width: 2px;
      background-color: #5b73f2;
      z-index: 10;
    }
    .scale-wrapper {
      display: flex;
      border-top: 1px solid #dddddd;
    }
    .scale-grip {
      position: relative;
      height: 100rpx;
      display: flex;
      &::before {
        content: "";
        position: absolute;
        top: 0;
        border-width: 1px;
        border-color: inherit;
        border-style: solid;
        height: 100%;
        transform: translateX(-50%);
        left: 0rpx;
      }
      &:last-child {
        &::after {
          content: "";
          position: absolute;
          top: 0;
          right: 0;
          border-width: 1px;
          border-color: inherit;
          border-style: solid;
          height: 100%;
        }
      }
    }
    .scale-grip-item {
      height: 60%;
      padding-top: 10rpx;
      &:not(:last-child) {
        border-right: 1px solid #000000;
      }
    }
    .scale-vaule-wrapper {
      position: relative;
      display: flex;
      text-align: center;
    }
    .scale-vaule {
      padding: 30rpx 0;
      transform: translateX(50%);
    }
    .first-scale-value {
      position: absolute;
      left: 0;
      bottom: 0;
      padding: 20rpx 0;
      transform: translateX(-50%);
    }
    .seat {
      flex-shrink: 0;
      box-sizing: border-box;
      border-top: 1px solid #ddd;
    }
  }
  /* .scale-container{
    display: flex;
  } */
  .vertical-box {
    height: 100%;
    .scroll-wrapper {
      position: relative;
    }
    .scroll-view {
      height: 100%;
    }
    .zz {
      position: absolute;
      top: 50%;
      left: 0;
      transform: translate(-50%);
      width: 40%;
      height: 2px;
      background-color: #5b73f2;
      z-index: 10;
    }
    .scale-container {
      display: flex;
      width: 100%;
    }
    .scale-wrapper {
      flex: 1;
    }
    .scale-grip {
      position: relative;
      border-left: 1px solid #000000;
      &:first-child {
        &::before {
          content: "";
          position: absolute;
          top: 0;
          left: 0;
          width: 80%;
          height: 0;
          border-top: 1px solid #dbdbdb;
        }
      }
    }
    .scale-grip-item {
      height: 60%;
      padding-top: 10rpx;
      border-bottom: 1px solid #000000;
    }
    .scale-vaule-wrapper {
      position: relative;
      text-align: left;
      flex: 1;
    }
    .scale-vaule {
    }
  }
  /* .vertical-box .scale-grip:last-child::after{
    content: "";
    position: absolute;
    top: 0;
    left:0;
    border-width: 1px;
    border-color: inherit;
    border-style: solid;
    width: 100%;
  } */
  /* .vertical-box .first-scale-value{
    position: absolute;
    left: 0;
    bottom: 0;
    padding: 20rpx 0;
    transform: translateX(-50%);
  } */
  /* .vertical-box .seat {
    flex-shrink: 0;
    box-sizing: border-box;
  } */

</style>
